/**
 * Copyright 2010, Lars J. Nilsson <http://www.larsan.net> 
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package net.larsan.dconf.cli.comm;

import static net.larsan.dconf.util.DNodes.findRoot;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.Properties;
import java.util.prefs.InvalidPreferencesFormatException;
import java.util.prefs.Preferences;

import net.larsan.dconf.DNode;
import net.larsan.dconf.DPath;
import net.larsan.dconf.cli.AbstractCommand;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options;

public class Import extends AbstractCommand {

	public Import() {
		super(new String[] { "import" }, "Import from file or URL");
	}

	@Override
	protected void doExec(CommandLine cl) {
		InputStream in = null;
		try {
			in = getInput(cl);
			if (in != null) {
				doImport(cl, in);
			}
		} catch (MalformedURLException e) {
			err("Malformed URL: " + cl.getOptionValue("u"));
			log.error("Failed to create URL", e);
		} catch (IOException e) {
			err("Failed to read input: " + e.getMessage());
			log.error("Failed to read input", e);
		} catch (InvalidPreferencesFormatException e) {
			err("Invalid format: " + e.getMessage());
			log.error("Invalid format", e);
		} finally {
			safeClose(in);
		}
	}

	@Override
	public String getArgumentSyntax() {
		return "[PATH]";
	}

	@Override
	protected void prepare(Options o) {
		o.addOption("u", true, "Set a URL to import from, must be valid");
		o.addOption("f", true, "Set a File to import from, acts as a shorthand for the URL import");
		o.addOption("p", false, "The target file is in properties format instead of XML");
	}

	// --- PRIVATE METHODS --- //

	private void doImport(CommandLine cl, InputStream in) throws IOException, InvalidPreferencesFormatException {
		if (cl.hasOption("p")) {
			importProperties(in);
		} else {
			Preferences.importPreferences(in);
		}
	}

	private void importProperties(InputStream in) throws IOException {
		Properties p = readProperties(in);
		DPath path = conn.getCurrentPath();
		DNode node = store.get(path);
		DNode root = findRoot(node);
		root.importProperties(p);
	}

	private Properties readProperties(InputStream in) throws IOException {
		Properties p = new Properties();
		p.load(in);
		return p;
	}

	private InputStream getInput(CommandLine cl) throws MalformedURLException, IOException {
		if (cl.hasOption("f")) {
			return new FileInputStream(createFileForInput(cl.getOptionValue("f")));
		} else if (cl.hasOption("u")) {
			return createURLForInput(cl.getOptionValue("u")).openStream();
		} else {
			err("Missing -u or -f option");
			return null;
		}
	}
}
